package com.chinackts.auth.service;

import com.chinackts.auth.model.MenuManagerType;
import com.chinackts.auth.repository.redis.MenuManagerRepository;
import com.chinackts.common.exception.ApplicationException;
import com.chinackts.common.okhttp.OkHttpRequest;
import com.chinackts.common.utils.menumanager.DecMenuManager;
import com.chinackts.common.utils.menumanager.InvtMenuManager;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Lianhong
 * @since 2021/12/3
 * 解密js
 * 抓取的不同接口的响应数据对应不同的解密JS，通过解密JS中的key进行解密
 * 目前仅保税核注清单使用 (2021-12-03)
 */
@Service
public class MenuManagerService {

    private static final Logger LOGGER = LoggerFactory.getLogger(MenuManagerService.class);


    private static final HashMap<MenuManagerType, String> MENU_MANAGER_URL_MAP = new HashMap<MenuManagerType, String>() {{
        put(MenuManagerType.Invt, "https://swapp.singlewindow.cn/invtwebserver/menuManger"); //保税核注清单查询解密js
        put(MenuManagerType.Dec, "https://swapp.singlewindow.cn/decserver/menuManger"); //报关单查询解密js
        put(MenuManagerType.Npts, "https://swapp.singlewindow.cn/nptsserver/menuManger"); //加工贸易手册查询解密js
        put(MenuManagerType.Nems, "https://swapp.singlewindow.cn/nemsserver/menuManger"); //加工贸易账册查询解密js
        put(MenuManagerType.Fec, "https://i.chinaport.gov.cn/fecwebserver/menuManger?ver=20200919"); //进出口收汇联查询解密js
    }};
    @Resource
    private MenuManagerRepository menuManagerRepository;
    @Resource(name = "proxyOkHttpRequest")
    private OkHttpRequest request;

    /**
     * 报关单查询解密js
     */
    public void menuManagerRequestAndStore(String id, MenuManagerType type) {
        boolean exists = this.menuManagerRepository.exists(id, type);
        if (exists) return;
        String url = MENU_MANAGER_URL_MAP.get(type);
        String result = request.get(url, null);
        if (StringUtils.isEmpty(result)) result = request.get(url, null);
        this.menuManagerRepository.saveMenuManager(id, this.menuManagerSplit(result), type);
    }

    /**
     * 解密
     */
    public String decode(String id, String response, MenuManagerType type) {
        String menuManagerStr = this.menuManagerRepository.getMenuManager(id, type);
        if (StringUtils.isEmpty(menuManagerStr)) {
            this.menuManagerRequestAndStore(id, type);
            menuManagerStr = this.menuManagerRepository.getMenuManager(id, type);
        }
        return this.decodeByType(response, menuManagerStr, type);
    }

    /**
     * 解密响应数据
     *
     * @param response 响应
     */
    private String decodeByType(String response, String menuManagerStr, MenuManagerType type) {
        if (StringUtils.isEmpty(menuManagerStr)) throw new ApplicationException("请重新初始化登录");
        String key = this.parseKeyFromMenuManager(menuManagerStr);
        if (StringUtils.isBlank(key)) {
            LOGGER.error("数据解析异常, 获取 menuManager Key 失败");
            throw new ApplicationException("9000", "数据解析异常");
        }
        if (MenuManagerType.Dec.equals(type)) response = DecMenuManager.mudata_kxc(response, key);
        if (MenuManagerType.Invt.equals(type)) response = InvtMenuManager.mudata_kxc(response, key);
        if (MenuManagerType.Npts.equals(type)) response = DecMenuManager.mudata_kxc(response, key);
        if (MenuManagerType.Nems.equals(type)) response = DecMenuManager.mudata_kxc(response, key);
        if (MenuManagerType.Fec.equals(type)) response = DecMenuManager.mudata_kxc(response, key);
        if (StringUtils.isBlank(response)) return StringUtils.EMPTY;
        return response;
    }

    /**
     * 获取 DES解密 所需的 key
     *
     * @return key
     */
    private String parseKeyFromMenuManager(String menuManagerStr) {
        Pattern keyPattern = Pattern.compile("varresult=MuData_KXC\\(str,'(.*?)'\\);");
        Matcher keyMatcher = keyPattern.matcher(menuManagerStr);
        String result = StringUtils.EMPTY;
        if (keyMatcher.find()) {
            result = keyMatcher.group(1);
        }
        return result;
    }

    /**
     * 截取 menuManager（取带有 key 的js代码片段）
     */
    private String menuManagerSplit(String menuManagerStr) {
        if (StringUtils.isEmpty(menuManagerStr)) return StringUtils.EMPTY;
        String[] menuTypeArr = menuManagerStr.split("function loadAESDecryptStr");
        if (menuTypeArr.length < 2) return StringUtils.EMPTY;
        return menuTypeArr[1].replaceAll(" ", "");
    }

}
